﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Infrastructure.ApllicationDto.DtoWcsManage;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Infrastructure.ApllicationDto;
using SqlSugar;
using StackExchange.Redis;
using Newtonsoft.Json;

namespace Zocono.WCS.Domain.PlcWriteDbDomain
{
    public class PlcWriteDbInfoService : IPlcWriteDbInfoService
    {
        private readonly ILogUtil _logUtil;
        private readonly IPlcWriteDbInfoRepository _PlcWriteDbInfoRepository;
        private readonly IMapper _Mapper;
        private readonly ISnowflake _Snowflake;
        private readonly IRedisHelper _IRedisHelper;

        //private readonly IRedisHelper _IRedisHelper;
        private readonly IDispatchEquipmentPlanarStateRepository _dispatchEquimentPlanarStateRepository;


        public PlcWriteDbInfoService(ISnowflake snowflake
            , IRedisHelper iRedisHelper, IPlcWriteDbInfoRepository PlcWriteDbInfoRepository, ILogUtil logUtil, IMapper mapper
            //, IRedisHelper redisHelper
            , IDispatchEquipmentPlanarStateRepository dispatchEquimentPlanarStateRepository)
        {
            _PlcWriteDbInfoRepository = PlcWriteDbInfoRepository;
            _logUtil = logUtil;
            _Mapper = mapper;
            _Snowflake = snowflake;
            _IRedisHelper = iRedisHelper;
            //_IRedisHelper = redisHelper;
            _dispatchEquimentPlanarStateRepository = dispatchEquimentPlanarStateRepository;
        }

        public async Task<long> AddPlcWriteDbInfoAsync(PlcWriteDbInfoDto PlcWriteDbInfoDto)
        {
            var PlcWriteDbInfo = _Mapper.Map<PlcWriteDbInfoDto, PlcWriteDbInfo>(PlcWriteDbInfoDto);
            long id = _Snowflake.GetId();
            PlcWriteDbInfo.ID = id;
            bool result = await _PlcWriteDbInfoRepository.InsertAsync(PlcWriteDbInfo);
            return result ? id : 0;
        }

        public async Task<bool> DeletePlcWriteDbInfoAsync(long ID)
        {
            bool result = await _PlcWriteDbInfoRepository.DeleteAsync(it => it.ID == ID);
            return result;
        }

        public async Task<bool> UpdatePlcWriteDbInfoAsync(PlcWriteDbInfoDto PlcWriteDbInfoDto)
        {
            var PlcWriteDbInfo = _Mapper.Map<PlcWriteDbInfoDto, PlcWriteDbInfo>(PlcWriteDbInfoDto);
            bool result = await _PlcWriteDbInfoRepository.UpdateAsync(PlcWriteDbInfo);
            return result;
        }

        public async Task<PageDto<PlcWriteDbInfoDto>> GetPlcWriteDbInfoAsync(QueryPlcWriteDbInfoDto queryPlcWriteDbInfoDto)
        {
            PageModel page = new PageModel { PageIndex = queryPlcWriteDbInfoDto.PageIndex, PageSize = queryPlcWriteDbInfoDto.PageSize, };
            var equipmentCode = queryPlcWriteDbInfoDto.EquipmentCode;
            var objectType = queryPlcWriteDbInfoDto.ObjectType;
            var dbCode = queryPlcWriteDbInfoDto.DbCode;
            var plcConnectionID = queryPlcWriteDbInfoDto.PlcConnectionId;
            var exp = Expressionable.Create<PlcWriteDbInfo, DispatchEquipmentInfo, PlcConnectionInfo>();
            exp.AndIF(plcConnectionID.HasValue && plcConnectionID != 0, (a, b, c) => a.PlcConnectionId == plcConnectionID);
            exp.AndIF(!string.IsNullOrEmpty(equipmentCode), (a, b, c) => a.EquipmentCode.ToString().Contains(equipmentCode));
            exp.AndIF(!string.IsNullOrEmpty(objectType), (a, b, c) => a.ObjectType.Contains(objectType));
            exp.AndIF(dbCode.HasValue && dbCode != 0, (a, b, c) => a.DbCode == dbCode);

            return await _PlcWriteDbInfoRepository.GetPlcWriteDbInfoAsync(exp.ToExpression(), page);
        }

        public async Task<PlcWriteDbInfoDto> GetPlcWriteDbInfoByIDAsync(long ID)
        {
            var result = await _PlcWriteDbInfoRepository.GetByIdAsync(ID);
            var vModel = _Mapper.Map<PlcWriteDbInfo, PlcWriteDbInfoDto>(result);
            return vModel;
        }

        public async Task<List<PlcWriteDbDto>> GetPlcWriteDbInfoAsync()
        {
            var list = await _PlcWriteDbInfoRepository.GetPlcWriteDbAsync();

            return list;
        }

        public async Task<List<DispatchEquipmentPlanarState>> GetDispatchEquipmentPlanarStateInfoAsync(List<string> equipmentCodes)
        {
            //优先从redis读取平面设备状态信息，redis存在再从数据库读取
            //List<RedisKey> listKey = new List<RedisKey>();
            List<DispatchEquipmentPlanarState> dispatchEquipmentPlanarStateList = new List<DispatchEquipmentPlanarState>();
            List<string> equipmentCodeList = equipmentCodes;

            var exp = Expressionable.Create<DispatchEquipmentPlanarState>();
            exp.AndIF(equipmentCodes.Count > 0, (a) => equipmentCodeList.Contains(a.EquipmentCode.ToString()));
            dispatchEquipmentPlanarStateList = await _dispatchEquimentPlanarStateRepository.GetListAsync(exp.ToExpression());
            //var list = await _dispatchEquimentPlanarStateRepository.GetListAsync(exp.ToExpression());
            //dispatchEquipmentPlanarStateList.AddRange(list);

            //foreach (var item in equipmentCodes)
            //    listKey.Add(new RedisKey(item));

            //dispatchEquipmentPlanarStateList = _IRedisHelper.GetStringKey<DispatchEquipmentPlanarState>(listKey);

            //if (dispatchEquipmentPlanarStateList.Count != equipmentCodes.Count)
            //{
            //    foreach (var item in dispatchEquipmentPlanarStateList)
            //    {
            //        if (equipmentCodeList.Exists(it => it == item.EquipmentCode.ToString()))
            //        {
            //            equipmentCodeList.Remove(item.EquipmentCode.ToString());
            //        }
            //    }

            //    //redis存在部分数据，不存在的从数据库读取
            //    var exp = Expressionable.Create<DispatchEquipmentPlanarState>();
            //    exp.AndIF(equipmentCodes.Count > 0, (a) => equipmentCodeList.Contains(a.EquipmentCode.ToString()));
            //    var list = await _dispatchEquimentPlanarStateRepository.GetListAsync(exp.ToExpression());
            //    dispatchEquipmentPlanarStateList.AddRange(list);

            //}
            //else if (dispatchEquipmentPlanarStateList.Count <= 0)
            //{
            //    //redis不存在从数据库读取
            //    var exp = Expressionable.Create<DispatchEquipmentPlanarState>();
            //    exp.AndIF(equipmentCodes.Count > 0, (a) => equipmentCodes.Contains(a.EquipmentCode.ToString()));
            //    dispatchEquipmentPlanarStateList = await _dispatchEquimentPlanarStateRepository.GetListAsync(exp.ToExpression());
            //}

            return dispatchEquipmentPlanarStateList;
        }
        public async Task<List<PlcWriteDbInfo>> GetPlcWriteDbInfoListAsync()
        {
            List<PlcWriteDbInfo> list = new();
            list = _IRedisHelper.GetStringKey<List<PlcWriteDbInfo>>("PlcWriteDbInfo");
            if (list == null || list.Count == 0)
            {
                list = await _PlcWriteDbInfoRepository.GetListAsync();
                _IRedisHelper.SetStringKey<List<PlcWriteDbInfo>>("PlcWriteDbInfo", list);
            }
            return list;
        }
    }
}
